using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Globalization;

namespace BigEaterCh
{
	/// <summary>
	/// Event handler for SelectedDate changed
	/// </summary>
	public delegate void SelectedDateChangedEventHandler(object sender, SelectedDateChangedEventArgs e);
	/// <summary>
	/// Summary description for UserControl1.
	/// </summary>
	public partial class UserCalendar : System.Windows.Forms.UserControl
	{

		#region Private variables

		private int pWidth;
		private int pHeight;
		private int pPicWidth;
		private int pPicHeight;

		private int intX=0;
		private int intY=0;

		private int _activeMonth=DateTime.Now.Month;
		private int _activeYear=DateTime.Now.Year;

    private DateTime[] _warningDates=null;
		//private DateTime p_SelectedDate=DateTime.Now;

    private SelectionRange _selectionRange = new SelectionRange(DateTime.MinValue, DateTime.MinValue);
		private bool _showGrid = true;
		private bool _showPrevNextButton = true;
		private bool _abbreviateWeekDayHeader=true;
		private bool _showCurrentMonthInDay=false;

		private Color p_BackgroundColor=Color.LightSteelBlue;
		private Color p_GridColor=Color.Black;
		private Color p_HeaderColor=Color.LightSteelBlue;
		private Color p_BoldedDateFontColor=Color.Red;
		private Color p_ActiveMonthColor=Color.White;
		private Color p_InactiveMonthColor=Color.Silver;
		private Color p_SelectedDayColor=Color.LightSteelBlue;
		private Color p_SelectedDayFontColor=Color.White;
		private Color p_NonselectedDayFontColor=Color.Black;
    private int p_GridWeight = 1;

    private Font fontHeader = new Font(Form.DefaultFont, FontStyle.Regular);
    private Font fontSelected = new Font(Form.DefaultFont, FontStyle.Regular);
    private Font fontWarning = new Font(Form.DefaultFont, FontStyle.Bold);

  	private readonly Rectangle[,] rects =  new Rectangle[7,6];
    private readonly Rectangle[] rectDays = new Rectangle[7];

    private DayOfWeek[] strDaysPoz = new DayOfWeek[7] { DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday, DayOfWeek.Saturday, DayOfWeek.Sunday };

    CultureInfo ci = new CultureInfo("pl-PL");

    private string GetMonthName(int mont)
    {
      if( mont>=1 && mont<=12 )
        return ci.DateTimeFormat.GetMonthName(mont).ToString();
      else
        return "Month error";
    }

    private string GetShortMonthName(int mont)
    {
      if( mont>=1 && mont<=12 )
        return ci.DateTimeFormat.GetAbbreviatedMonthName(mont).ToString();
      else
        return "Month error";
    }

    private string GetDayName(DayOfWeek mont)
    {
      return ci.DateTimeFormat.GetDayName(mont).ToString();
    }

    private string GetDayShortName(DayOfWeek mont)
    {
      return ci.DateTimeFormat.GetAbbreviatedDayName(mont).ToString();
    }

		
		private bool bDesign = true;

		private Pen penGrid;
    private Pen penGridBold;

		private Color ActiveDarker;
		private Color InActiveDarker;
    private Color HeaderDarker;
    private Color SelectedDayDarker;
		private SolidBrush brushHeader;
    private SolidBrush brushHeaderDarker;
    private SolidBrush brushActive;
		private SolidBrush brushInactive;
		private SolidBrush brushActiveDarker;
		private SolidBrush brushInactiveDarker;
		private SolidBrush brushSelectedDay;
    private SolidBrush brushSelectedDayDarker;
		private SolidBrush brushSelectedDayFont;
		private SolidBrush brushNonselectedDayFont;
		private SolidBrush brushBoldedDateFont;
    private SolidBrush brushBackground;


		private StringFormat sf;
		private StringFormat sfHeader;

		//new version

		private DateTime[,] arrDates;

		#endregion Private variables

		#region Custom events
		/// <summary>
		/// Event handler definition
		/// </summary>
		public event SelectedDateChangedEventHandler SelectedDateChanged;

		/// <summary>
		/// Raises event by invoking delegate
		/// </summary>
		/// <param name="eventArgs"></param>
		protected virtual void OnSelectedDateChanged(SelectedDateChangedEventArgs eventArgs)
		{
			if(SelectedDateChanged!=null)
			{
				SelectedDateChanged(this,eventArgs);
			}
		}
		#endregion Custom events

		#region Properties

    /// <summary>
    /// The year of the active month
    /// </summary>
    [Description("The year portion of the month, year to display.")]
 //   [Category("MPK_Calendar")]
    public int ActiveYear
    {
      get
      {
        return _activeYear;
      }
      set
      {
        _activeYear=value;
      }
    }

    /// <summary>
    /// The number of the active month.
    /// </summary>
    [Description("The month portion of the month, year to display.")]
//    [Category("MPK_Calendar")]
    public int ActiveMonth
    {
      get
      {
        return _activeMonth;
      }
      set
      {
        if( value<1 )
        {
          _activeMonth=1;
        }
        else if( value>12 )
        {
          _activeMonth=12;
        }
        else
        {
          _activeMonth=value;
        }
      }
    }
		
		/// <summary>
		/// Array of dates to be bolded.
		/// </summary>
    [Description("Warning Dates")]
	//	[Category("MPK_Calendar")]
    public DateTime[] WarningDates
		{
			get
			{

        return _warningDates;

			}
			set
			{
        _warningDates = value;
				//look at each date and see if it corresponds with a date in the grid
        if( _warningDates!=null )
				{
          Array.Sort(_warningDates);
				}

				
			}

		}
	
		/// <summary>
		/// The selected date.
		/// </summary>
		[Description("The selected dates start")]
	//	[Category("MPK_Calendar")]
    public DateTime SelectionRangeStart
		{
			get
			{
        return _selectionRange.Start;
			}
			set
			{
        _selectionRange.Start = value;
        SelectedDateChangedEventArgs eventArgs = new SelectedDateChangedEventArgs(_selectionRange);
				OnSelectedDateChanged(eventArgs);
			}
		}

    public void ResetSelectionRange()
    {
      _selectionRange.Start = DateTime.MinValue;
      _selectionRange.End = DateTime.MinValue;
      pictureBoxWork.Invalidate();
    }

    [Description("The selected dates end")]
//    [Category("MPK_Calendar")]
    public DateTime SelectionRangeEnd
    {
      get
      {
        return _selectionRange.End;
      }
      set
      {
        _selectionRange.End = value;
        SelectedDateChangedEventArgs eventArgs = new SelectedDateChangedEventArgs(_selectionRange);
        OnSelectedDateChanged(eventArgs);
      }
    }


		/// <summary>
		/// Property - Determines whether the Previous and Next buttons are visible.
		/// </summary>
		[Description("Determines whether the Previous and Next buttons are visible.")]
	//	[Category("MPK_Calendar")]
		public bool ShowPrevNextButton
		{
			get
			{
				return _showPrevNextButton;
			}
			set
			{
				_showPrevNextButton = value;
				this.buttonNext.Visible=_showPrevNextButton;
				this.buttonPrev.Visible=_showPrevNextButton;
			}
		}

		/// <summary>
		/// Property - Determines whether or not the grid is drawn.
		/// </summary>
		[Description("Determines whether or not the grid is drawn.")]
	//	[Category("MPK_Calendar")]
		public bool ShowGrid
		{
			get
			{
				return _showGrid;
			}
			set
			{
				_showGrid = value;
				pictureBoxWork.Invalidate();
			}
		}

		/// <summary>
		/// Property - Determines whether or not to abbreviate the weekday in the header.
		/// </summary>
		[Description("Determines whether or not to abbreviate the weekday in the header.")]
		//[Category("MPK_Calendar")]
		public bool AbbreviateWeekDayHeader
		{
			get
			{
				return _abbreviateWeekDayHeader;
			}
			set
			{
				_abbreviateWeekDayHeader = value;
			}
		}

		/// <summary>
		/// Property - Determines whether or not to display the month name in each day of the current month.
		/// </summary>
		[Description("Determines whether or not to display the month name in each day of the current month.")]
		//[Category("MPK_Calendar")]
		public bool ShowCurrentMonthInDay
		{
			get
			{
				return _showCurrentMonthInDay;
			}
			set
			{
				_showCurrentMonthInDay = value;
			}
		}

		/// <summary>
		/// Property - Grid color.
		/// </summary>
		[Description("Grid color.")]
		//[Category("MPK_Calendar")]
		public Color GridColor
		{
			get
			{
				return p_GridColor;
			}
			set
			{
				p_GridColor=value;
				this.pictureBoxWork.Invalidate();
			}
		}

    /// <summary>
    /// Property - Grid color.
    /// </summary>
    [Description("Grid weight.")]
  //  [Category("MPK_Calendar")]
    public int GridWeight
    {
      get
      {
        return p_GridWeight;
      }
      set
      {
        p_GridWeight=value;
        this.pictureBoxWork.Invalidate();
      }
    }

		/// <summary>
		/// Property - Header background color.
		/// </summary>
		[Description("Header background color.")]
		//[Category("MPK_Calendar")]
		public Color HeaderColor
		{
			get
			{
				return p_HeaderColor;
			}
			set
			{
				p_HeaderColor=value;
				this.pictureBoxWork.Invalidate();
			}
		}

		/// <summary>
		/// Property - Control background color.
		/// </summary>
		[Description("Background color.")]
		//[Category("MPK_Calendar")]
		public Color BackgroundColor
		{
			get
			{
				return p_BackgroundColor;
			}
			set
			{
				p_BackgroundColor=value;
				this.BackColor = p_BackgroundColor;
			}
		}

		/// <summary>
		/// Property - Color of the active month.
		/// </summary>
		[Description("Color of the active month.")]
		//[Category("MPK_Calendar")]
		public Color ActiveMonthColor
		{
			get
			{
				return p_ActiveMonthColor;
			}
			set
			{
				p_ActiveMonthColor = value;
				this.pictureBoxWork.Invalidate();
			}
		}

		/// <summary>
		/// Property - Color of the inactive month.
		/// </summary>
		[Description("Color of the inactive month.")]
		//[Category("MPK_Calendar")]
		public Color InactiveMonthColor
		{
			get
			{
				return p_InactiveMonthColor;
			}
			set
			{
				p_InactiveMonthColor = value;
				this.pictureBoxWork.Invalidate();
			}
		}

		/// <summary>
		/// Property - Color for bolded dates font.
		/// </summary>
		[Description("Color for bolded dates font.")]
		//[Category("MPK_Calendar")]
		public Color BoldedDateFontColor
		{
			get
			{
				return p_BoldedDateFontColor;
			}
			set
			{
				p_BoldedDateFontColor = value;
			}
		}

		/// <summary>
		/// Property - Color of the background for selected day.
		/// </summary>
		[Description("Color of the background for selected day.")]
		//[Category("MPK_Calendar")]
		public Color SelectedDayColor
		{
			get
			{
				return p_SelectedDayColor;
			}
			set
			{
				p_SelectedDayColor = value;
			}
		}

		/// <summary>
		/// Property - Color of the text for selected day.
		/// </summary>
		[Description("Color of the text for selected day.")]
		//[Category("MPK_Calendar")]
		public Color SelectedDayFontColor
		{
			get
			{
				return p_SelectedDayFontColor;
			}
			set
			{
				p_SelectedDayFontColor = value;
			}
		}

		/// <summary>
		/// Property - Color of the text for non-selected days.
		/// </summary>
		[Description("Color of the text for non-selected days.")]
		//[Category("MPK_Calendar")]
		public Color NonselectedDayFontColor
		{
			get
			{
				return p_NonselectedDayFontColor;
			}
			set
			{
				p_NonselectedDayFontColor = value;
			}
		}

		/// <summary>
		/// Property - Font for bolded days.
		/// </summary>
		[Description("Font for selected days.")]
		//[Category("MPK_Calendar")]
		public Font SelectedFont
		{
			get
			{
				return fontSelected;
			}
			set
			{
				fontSelected = value;
			}
		}

		/// <summary>
		/// Property - Font for not bolded days.
		/// </summary>
		[Description("Font for warning days.")]
		//[Category("MPK_Calendar")]
		public Font WarningFont
		{
			get
			{
				return fontWarning;
			}
			set
			{
				fontWarning = value;
			}
		}

		/// <summary>
		/// Property - Header text font.
		/// </summary>
		[Description("Header text font.")]
		//[Category("MPK_Calendar")]
		public Font HeaderFont
		{
			get
			{
				return fontHeader;
			}
			set
			{
				fontHeader = value;
			}
		}

    /// <summary>
    /// Property - Header text font.
    /// </summary>
    [Description("Title text font.")]
    //[Category("MPK_Calendar")]
    public Font TitleFont
    {
      get
      {
        return labelMonthName.Font;
      }
      set
      {
        labelMonthName.Font = value;
      }
    }


		#endregion Properties
		
		#region Constructor

		/// <summary>
		/// Constructor
		/// </summary>
		public UserCalendar()
		{
			// This call is required by the Windows.Forms Form Designer.
			InitializeComponent();

			// TODO: Add any initialization after the InitComponent call
			//SelectedDate = DateTime.Now;
		}

		#endregion Constructor

		#region Control events



		private void MPK_Calendar_SizeChanged(object sender, System.EventArgs e)
		{
			pWidth = this.Size.Width;
			pPicWidth=pWidth;
			pHeight = this.Size.Height;
			pPicHeight=pHeight-35;
			pictureBoxWork.Width=pPicWidth;
			pictureBoxWork.Height=pPicHeight;
			//keep the buttons in the same place
			buttonPrev.Left = 5;
			buttonNext.Left = this.Width - buttonNext.Width - 5;
			labelMonthName.Left = (this.Width - labelMonthName.Width)/2;
			CreateGrid(pictureBoxWork.Width,pictureBoxWork.Height);
			pictureBoxWork.Invalidate();
		}

		private void picMPK_Cal_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
		{
      if( ( Control.ModifierKeys&Keys.Control )==Keys.Control )
      {
        intX = e.X;
        intY = e.Y;
        int inti = 0;
        int intj = 0;
        for( int j = 0 ; j<6 ; j++ )
        {
          //for(int i = 0;i<7i++)
          for( int i = 0 ; i<7 ; i++ )
          {
            if( rects[i, j].Contains(intX, intY) )
            {
              inti = i;
              intj = j;

              if( ActiveMonth == arrDates[i, j].Month && _activeYear == arrDates[i, j].Year )
              {

                if( arrDates[i, j]<this._selectionRange.Start )
                {
                  this._selectionRange.End = this._selectionRange.Start;
                  this._selectionRange.Start = arrDates[i, j];
                }
                else if( arrDates[i, j]>this._selectionRange.Start )
                {
                  this._selectionRange.End= arrDates[i, j];
                }
                SelectedDateChangedEventArgs eventArgs = new SelectedDateChangedEventArgs(_selectionRange);
                OnSelectedDateChanged(eventArgs);
              }
            }
          }
        }
      }
      else
      {
        intX = e.X;
        intY = e.Y;
        int inti = 0;
        int intj = 0;
        for( int j = 0 ; j<6 ; j++ )
        {
          //for(int i = 0;i<7i++)
          for( int i = 0 ; i<7 ; i++ )
          {
            if( rects[i, j].Contains(intX, intY) )
            {
              inti = i;
              intj = j;

              if( ActiveMonth == arrDates[i, j].Month && _activeYear == arrDates[i, j].Year )
              {
                this._selectionRange.Start = arrDates[i, j];
                this._selectionRange.End= arrDates[i, j];

                SelectedDateChangedEventArgs eventArgs = new SelectedDateChangedEventArgs(_selectionRange);
                OnSelectedDateChanged(eventArgs);
              }
            }
          }
        }
      }

			pictureBoxWork.Invalidate();
		}

    void picMPK_Cal_MouseHover(object sender, EventArgs e)
    {
      //intX = e.X;
      //intY = e.Y;
      //int inti = 0;
      //int intj = 0;
      //for( int j = 0 ; j<6 ; j++ )
      //{
      //  //for(int i = 0;i<7i++)
      //  for( int i = 0 ; i<7 ; i++ )
      //  {
      //    if( rects[i, j].Contains(intX, intY) )
      //    {
      //      inti = i;
      //      intj = j;

      //      //update
      //      this.SelectionRange.Start = arrDates[i, j];


      //      //update
      //      intMonth = arrDates[i, j].Month;
      //    }
      //  }

      //}
      //picMPK_Cal.Invalidate();
    }

    void picMPK_Cal_MouseMove(object sender, MouseEventArgs e)
    {
      if( (e.Button&System.Windows.Forms.MouseButtons.Left) == System.Windows.Forms.MouseButtons.Left)
      {
        intX = e.X;
        intY = e.Y;
        int inti = 0;
        int intj = 0;
        for( int j = 0 ; j<6 ; j++ )
        {
          //for(int i = 0;i<7i++)
          for( int i = 0 ; i<7 ; i++ )
          {
            if( rects[i, j].Contains(intX, intY) )
            {
              inti = i;
              intj = j;

              if( ActiveMonth == arrDates[i, j].Month && _activeYear == arrDates[i, j].Year )
              {

                //update

                if( arrDates[i, j]<this._selectionRange.Start )
                {
                  this._selectionRange.End = this._selectionRange.Start;
                  this._selectionRange.Start = arrDates[i, j];
                }
                else if( arrDates[i, j]>this._selectionRange.Start )
                {
                  this._selectionRange.End= arrDates[i, j];
                }

                SelectedDateChangedEventArgs eventArgs = new SelectedDateChangedEventArgs(_selectionRange);
                OnSelectedDateChanged(eventArgs);
              }
            }
          }

        }
        pictureBoxWork.Invalidate();
      }
    }


		//this is not used when displaying appointment data
		private void btnPrev_Click(object sender, System.EventArgs e)
		{
			if(ActiveMonth==1)
			{
				ActiveMonth=12;
				_activeYear=_activeYear-1;
			}
			else
			{
				ActiveMonth--;
			}
			//update
      //if( SelectionRange.Start!=DateTime.MinValue )
      //  this.SelectionRange.Start = this.SelectionRange.Start.AddMonths(-1);
      //if( SelectionRange.Start!=DateTime.MinValue )
      //  this.SelectionRange.End = this.SelectionRange.End.AddMonths(-1);
      pictureBoxWork.Invalidate();

		}

		//this is not used when displaying appointment data
		private void btnNext_Click(object sender, System.EventArgs e)
		{
			if(ActiveMonth==12)
			{
				ActiveMonth=1;
				_activeYear++;
			}
			else
			{
				ActiveMonth++;
			}
			//update
      //if( SelectionRange.Start!=DateTime.MaxValue )
      //  this.SelectionRange.Start = this.SelectionRange.Start.AddMonths(1);
      //if( SelectionRange.Start!=DateTime.MaxValue )
      //  this.SelectionRange.End = this.SelectionRange.End.AddMonths(1);
      pictureBoxWork.Invalidate();
		}

		private void picMPK_Cal_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
		{
			bool dayInActiveMonth = false;
			bool selectedDay = false;
			bool warningDay = false;
      bool weeckDay = false;

      if( !bDesign )
			{
				CreateDataTable();
				CreateGraphicObjects();

				//update
				//label at top
        
				this.labelMonthName.Text = GetMonthName(ActiveMonth) + " " + _activeYear.ToString();

				Rectangle rect = e.ClipRectangle;
				rect.Y +=20;
				rect.Height-=20;
				//graphics object for paint event
				Graphics g = e.Graphics;
        g.FillRectangle(brushBackground, rect);
				string str;
				//day of week header
				for(int i = 0;i<7;i++)
				{
          weeckDay= strDaysPoz[i]== DayOfWeek.Saturday || strDaysPoz[i]== DayOfWeek.Sunday?true:false;
          //draw weekday header rectangle
          if( weeckDay)//weekend
          {
            g.FillRectangle(brushHeaderDarker, rectDays[i]);
          }
          else//weekday
          {
            g.FillRectangle(brushHeader, rectDays[i]);
          }

					//draw rectnagle for grid if requested
					if(_showGrid)
					{
            g.DrawRectangle(penGrid, rectDays[i]);
					}
					//draw weekday header
					if(_abbreviateWeekDayHeader)
					{
						g.DrawString( GetDayShortName(strDaysPoz[i]),fontHeader, Brushes.Black,rectDays[i],sfHeader);
					}
					else
					{
            g.DrawString(GetDayName(strDaysPoz[i]), fontHeader, Brushes.Black, rectDays[i], sfHeader);
					}

				}

				//actual calendar 
				for(int j = 0;j<6;j++)
				{
					for(int i = 0;i<7;i++)
					{
            weeckDay= arrDates[i, j].DayOfWeek== DayOfWeek.Saturday || arrDates[i, j].DayOfWeek== DayOfWeek.Sunday?true:false;

            ////rects for text
            Rectangle rectTopHalf = new Rectangle(rects[i,j].X,rects[i,j].Y,rects[i,j].Width,(int)(rects[i,j].Height*0.5));
            Rectangle rectHalfEnd = new Rectangle(rects[i, j].X, rects[i, j].Y+(int)(rects[i,j].Height*0.5), rects[i, j].Width, rects[i, j].Height-(int) ( rects[i, j].Height*0.5 ));

						//check to see if day is in active month
						//update
						if(arrDates[i,j].Month==_activeMonth)
						{
							dayInActiveMonth=true;
							//add month name to box if requested
							if(_showCurrentMonthInDay)
							{
								//update
								str=GetShortMonthName(ActiveMonth) + " " + arrDates[i,j].Day.ToString();
							}
							else
							{

								//update
								str=arrDates[i,j].Day.ToString();
							}

							//update
							DateTime dateTest = arrDates[i,j];
							//should box be filled as selected date

              if( dateTest.Date>=this._selectionRange.Start && dateTest.Date<=this._selectionRange.End )
							{
								selectedDay = true;
							}
							else
							{
								selectedDay = false;
							}

							//check to see if date is in BoldedDates
							//first, are there any BoldedDates?
              if( _warningDates!=null )//yes, there are BoldedDates
							{
								//do any dates match the date for this rectangle?
                if( Array.IndexOf(_warningDates, dateTest)>-1 )
								{
									warningDay = true;
								}
								else//no match
								{
									warningDay=false;
								}
							}
							else//no BoldedDates
							{
								warningDay=false;
							}

						}
						else//not the active month
						{
							//update
							str=arrDates[i,j].Day.ToString();
							dayInActiveMonth=false;
							selectedDay=false;
						}

						/////////////////////////////////////////////////////////////////////////////
            if( selectedDay )//selected date
            {
							if(weeckDay )//weekend
                g.FillRectangle(brushSelectedDayDarker, rects[i, j]);
							else//weekday
                g.FillRectangle(brushSelectedDay, rects[i, j]);

              if( warningDay )
                g.DrawString(str, fontWarning, brushBoldedDateFont, rectTopHalf, sfHeader);
              else
                g.DrawString(str, fontSelected, brushNonselectedDayFont, rectTopHalf, sfHeader);
            }
						else if(dayInActiveMonth)//not selected but active
						{
							if(weeckDay)//weekend
								g.FillRectangle(brushActiveDarker,rects[i,j]);
							else//weekday
								g.FillRectangle(brushActive,rects[i,j]);

              if( warningDay )
                g.DrawString(str, fontWarning, brushBoldedDateFont, rectTopHalf, sfHeader);
              else
                g.DrawString(str, Font, brushNonselectedDayFont, rectTopHalf, sfHeader);
            }
						else//not selected or active
						{
              if( weeckDay)//weekend
								g.FillRectangle(brushInactiveDarker,rects[i,j]);
							else//weekday
								g.FillRectangle(brushInactive,rects[i,j]);
						}

            if( _showGrid )
            {
               g.DrawRectangle(penGrid, rects[i, j]);
            }
					}
				}
			}
		}

		#endregion Control events

		#region Private functions

		private void CreateGraphicObjects()
		{
			//these are the objects that will be used in the paint event
			//pens
      penGrid = new Pen(p_GridColor, p_GridWeight);
      penGridBold = new Pen(p_GridColor, p_GridWeight*2);

			//brushes
      brushBackground =  new SolidBrush(Color.FromKnownColor(KnownColor.Control) );//      Brushes.DarkGray
      brushHeader = new SolidBrush(p_HeaderColor);
      HeaderDarker = Color.FromArgb((int) ( p_HeaderColor.R*0.9 ), (int) ( p_HeaderColor.G*0.9 ), (int) ( p_HeaderColor.B*0.9 ));
      brushHeaderDarker = new SolidBrush(HeaderDarker);

			brushActive = new SolidBrush(p_ActiveMonthColor);
			ActiveDarker = Color.FromArgb((int)(p_ActiveMonthColor.R*0.9),(int)(p_ActiveMonthColor.G*0.9),(int)(p_ActiveMonthColor.B*0.9));
			brushActiveDarker = new SolidBrush(ActiveDarker);

			brushInactive = new SolidBrush(p_InactiveMonthColor);
			InActiveDarker = Color.FromArgb((int)(p_InactiveMonthColor.R*0.9),(int)(p_InactiveMonthColor.G*0.9),(int)(p_InactiveMonthColor.B*0.9));
			brushInactiveDarker = new SolidBrush(InActiveDarker);

			brushSelectedDay = new SolidBrush(p_SelectedDayColor);
      SelectedDayDarker = Color.FromArgb((int) ( p_SelectedDayColor.R*0.9 ), (int) ( p_SelectedDayColor.G*0.9 ), (int) ( p_SelectedDayColor.B*0.9 ));
      brushSelectedDayDarker = new SolidBrush(SelectedDayDarker);

      brushBoldedDateFont = new SolidBrush(p_BoldedDateFontColor);
			brushSelectedDayFont = new SolidBrush(p_SelectedDayFontColor);
			brushNonselectedDayFont = new SolidBrush(p_NonselectedDayFontColor);

			//stringformats for displaying text
			//this is used to display appointment text in each day box
			//the text is left aligned and trimmed to fit with ellipsis
			sf = new StringFormat();
			sf.Alignment = StringAlignment.Near;//left
			sf.LineAlignment = StringAlignment.Center;
			sf.Trimming = StringTrimming.EllipsisCharacter;
			//this is used for day header and day numbers
			//the text is centered vertically and horizontally
			sfHeader = new StringFormat();
			sfHeader.Alignment = StringAlignment.Center;
			sfHeader.LineAlignment = StringAlignment.Center;
		}

		private void CreateGrid(int intW,int intH)
		{
      int intHH = 20;			
			int intXX=0;
			int intXSize = (int)Math.Floor((double)(intW-10)/7);
			int intYSize = (int)Math.Floor((double)(intH-10-intHH)/6);

			int intYY = 5;
			intXX=5;
			for(int i = 0;i<7;i++)
			{
        rectDays[i] = new Rectangle(intXX, intYY, intXSize, intHH);
        intXX += intXSize;
			}

      intYY +=intHH;
			for(int j = 0;j<6;j++)
			{
				intXX=5;
				for(int i = 0;i<7;i++)
				{
          rects[i, j] = new Rectangle(intXX, intYY, intXSize, intYSize);
					intXX += intXSize;
				}
				intYY += intYSize;
			}
		}

    private void CreateDataTable()
		{

			int intDayofWeek=0;
			int intWeek = 0;

			//total day counter
			int intTotalDays=-1;

			//this is where the first day of the month falls in the grid
			int intFirstDay=0;

      int prevYear= _activeYear;
      int prevMonth=_activeMonth;

      int nextYear= _activeYear;
      int nextMonth=_activeMonth;

      if( _activeMonth ==1)
      {
        prevYear= _activeYear-1;
        prevMonth=12;

        nextYear= _activeYear;
        nextMonth=_activeMonth+1;
      }
      else if( _activeMonth ==12 )
      {
        prevYear= _activeYear;
        prevMonth=_activeMonth-1;

        nextYear= _activeYear+1;
        nextMonth=1;
      }
      else
      {
        prevYear= _activeYear;
        prevMonth=_activeMonth-1;

        nextYear= _activeYear;
        nextMonth=_activeMonth+1;
      }


			//number of days in active month
      int intCurrDays = DateTime.DaysInMonth(_activeYear, _activeMonth);
			
			//number of days in active month
			int intPrevDays = DateTime.DaysInMonth(prevYear,prevMonth);
			
			//number of days in active month
			int intNextDays = DateTime.DaysInMonth(nextYear,nextMonth);
			

			DateTime[] datesCurr = new DateTime[intCurrDays];
			DateTime[] datesPrev = new DateTime[intPrevDays];
			DateTime[] datesNext = new DateTime[intNextDays];

			for(int i = 0;i<intCurrDays;i++)
			{
        datesCurr[i] = new DateTime(_activeYear, _activeMonth, i+1);
			}

			for(int i = 0;i<intPrevDays;i++)
			{
				datesPrev[i] = new DateTime(prevYear,prevMonth,i+1);
			}

			for(int i = 0;i<intNextDays;i++)
			{
				datesNext[i] = new DateTime(nextYear,nextMonth,i+1);
			}

			//array to hold dates corresponding to grid
			arrDates  = new DateTime[7,6];//dates ahead of current date

			//where does the first day of the week land?
      intDayofWeek = Array.IndexOf(strDaysPoz, datesCurr[0].DayOfWeek);


			for(int intDay = 0;intDay<intCurrDays;intDay++)
			{
				//populate array of dates for active month, this is used to tell what day of the week each day is

        intDayofWeek = Array.IndexOf(strDaysPoz, datesCurr[intDay].DayOfWeek);


				//fill the array with the day numbers
				arrDates[intDayofWeek,intWeek] = datesCurr[intDay];
				if(intDayofWeek==6)
				{
					intWeek++;
				}

				//Back fill any days from the previous month
				//this is does here because I needed to know where the first day of the active month fell in the grid
				if(intDay==0)
				{
					intFirstDay=intDayofWeek;
					//Days in previous month
					int intDaysPrev = intPrevDays;

					//if the first day of the active month is not sunday, count backwards and fill in day number
					if(intDayofWeek>0)
					{
						for(int i = intDayofWeek-1;i>=0;i--)
						{
							arrDates[i,0] = datesPrev[intDaysPrev-1];
							intDaysPrev--;
							intTotalDays++;
						}
					}
				}
				intTotalDays++;
			}//for

			//fill in the remaining days of the grid with the beginning of the next month

			intTotalDays++;
			//what row did we leave off in for active month?
			int intRow = intTotalDays/7;

			int intCol;

			int intDayNext=0;

			for(int i = intRow;i<6;i++)
			{
				intCol = intTotalDays - (intRow*7);
				for(int j = intCol;j<7;j++)
				{
					arrDates[j,i] = datesNext[intDayNext];
					intDayNext++;
					intTotalDays++;
				}	
				intRow++;
			}
		}
    #endregion Private functions

    #region Form events

    private void MPK_Calendar_Load(object sender, System.EventArgs e)
		{
			pWidth = this.Size.Width;
			pPicWidth=pWidth;
			pHeight = this.Size.Height;
			pPicHeight=pHeight-35;
			pictureBoxWork.Width=pPicWidth;
			pictureBoxWork.Height=pPicHeight;
			CreateGrid(pictureBoxWork.Width,pictureBoxWork.Height);
			//FillDates();
			buttonPrev.Visible = _showPrevNextButton;
			buttonNext.Visible = _showPrevNextButton;
			CreateGraphicObjects();
			bDesign = false;

		}

		#endregion Form events
  }
}
